package com.douqu.game.core.entity.ext.data.challenge;

import com.bean.core.buffer.ByteBuffer;
import com.douqu.game.core.config.common.CommonData;
import com.douqu.game.core.config.map.WorldMapTaskBoxConfig;
import com.douqu.game.core.config.map.WorldMapTaskConfig;
import com.douqu.game.core.config.map.WorldMapTaskGroupConfig;
import com.douqu.game.core.entity.Player;
import com.douqu.game.core.entity.db.CardDB;
import com.douqu.game.core.entity.ext.TaskInfo;
import com.douqu.game.core.entity.ext.data.BaseData;
import com.douqu.game.core.factory.ConfigFactory;
import com.douqu.game.core.factory.ConstantFactory;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.factory.TaskFactory;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * 大地图 战场争锋
 * @author: miracle.
 * Description:
 * Date: 2018/5/4 0004 下午 6:49
 * Huan Yu Copyright (c) 2017 All Rights Reserved.
 */
public class WorldMapTaskData extends BaseData {

    /**
     * 单人战场是否毕业
     */
    private boolean singleMapEnd;
    /**
     * 争霸赛数据
     */
    private WorldMapKillData killData;

    //每日4点 保存玩家的等级
    private int lastGrade;
    //今日当前军功值
    private int militaryExploitValue;

    /**
     * key    是类型
     * value  是完成度
     */
    private Map<Integer,WorldMapTaskBean> worldMapTaskValues = new HashMap<>();

    //重置时间
    private long resetTaskTime;

    //已经领取的宝箱
    private List<Integer> boxList;

    /** 本次活动参战英雄 */
    private List<CardDB> battleCardList;

    private Player player;

    public WorldMapTaskData(Player player)
    {
        this.player = player;

        killData = new WorldMapKillData(player);

        clear();
    }

    @Override
    public void init() {
        killData.init();
    }

    @Override
    public void checkInit() {
        killData.checkInit();
    }

    //每日四点执行
    @Override
    public void reset()
    {
        militaryExploitValue = 0;
        resetTaskTime = DataFactory.currentTime;
        boxList = new CopyOnWriteArrayList<>();

        initPlayerGrade();
        initTaskId();
        killData.reset();
    }

    //登录执行
    @Override
    public void checkReset() {
        if(!CoreUtils.isTodayByOffset(resetTaskTime, DataFactory.currentTime, ConstantFactory.DEFAULT_RESET_FRESH_TIMES_HOUR)){
            reset();
        }
    }

    @Override
    public void writeTo(ByteBuffer buffer) {

        buffer.writeShort(lastGrade);
        buffer.writeInt(militaryExploitValue);
        buffer.writeByte(worldMapTaskValues.size());
        for (Map.Entry<Integer,WorldMapTaskBean> entry:worldMapTaskValues.entrySet()){
            buffer.writeByte(entry.getKey());
            entry.getValue().writeTo(buffer);
        }
        buffer.writeLong(resetTaskTime);
        buffer.writeByte(boxList.size());
        for (Integer integer : boxList){
            buffer.writeShort(integer);
        }

        buffer.writeByte(battleCardList.size());
        for(CardDB cardDB : battleCardList)
        {
            cardDB.writeTo(buffer);
        }

        killData.writeTo(buffer);

        buffer.writeBoolean(false);
    }

    @Override
    public void loadFrom(ByteBuffer buffer)
    {
        lastGrade = buffer.readShort();
        militaryExploitValue = buffer.readInt();
        int size = buffer.readByte();
        int key;
        for (int i = 0; i < size; i++){
            key = buffer.readByte();
            WorldMapTaskBean worldMapTaskBean = new WorldMapTaskBean();
            worldMapTaskBean.loadFrom(buffer);
            worldMapTaskValues.put(key,worldMapTaskBean);
        }

        resetTaskTime = buffer.readLong();
        size = buffer.readByte();
        for (int i = 0; i < size; i++){
            boxList.add(buffer.readShort());
        }

        size = buffer.readByte();
        CardDB cardDB = null;
        for(int i = 0; i < size; i++)
        {
            cardDB = new CardDB(player);
            cardDB.loadFrom(buffer);
            battleCardList.add(cardDB);
        }

        killData.loadFrom(buffer);

        buffer.readBoolean();
    }

    /**
     * 初始化 战场争锋玩家的等级
     */
    public void initPlayerGrade()
    {
        if(player != null)
            lastGrade = player.getLv();
    }

    /**
     * 初始化 战场争锋玩家的任务id
     */
    public void initTaskId(){
        worldMapTaskValues = new HashMap<>();
        worldMapTaskValues.put(SGCommonProto.E_WORLDMAPTASK_TYPE.WORLD_MAP_TASK_KILL_GENERAL_VALUE, new WorldMapTaskBean(0L,ConstantFactory.WORLD_MAP_TASK_KILL_GENERAL_FIRST_ID));
        worldMapTaskValues.put(SGCommonProto.E_WORLDMAPTASK_TYPE.WORLD_MAP_TASK_KILL_CARD_VALUE, new WorldMapTaskBean(0L,ConstantFactory.WORLD_MAP_TASK_KILL_CARD_FIRST_ID));
        worldMapTaskValues.put(SGCommonProto.E_WORLDMAPTASK_TYPE.WORLD_MAP_TASK_KILL_CITY_VALUE, new WorldMapTaskBean(0L,ConstantFactory.WORLD_MAP_TASK_KILL_CITY_FIRST_ID));
    }

    /**
     * 获取经验
     * @return
     */
    public int getTodayExp(){
        /**
         * 获取玩家这个等级的军功上限 和 玩家当前的军功
         * 1.如果大于等级上限 返回等级上限
         * 2.否则返回当前的军功值
         */
        int exp = 0;
        WorldMapTaskGroupConfig groupConfig = getGroupConfig();
        if (groupConfig != null){
            exp = militaryExploitValue > groupConfig.count ? groupConfig.count:militaryExploitValue;
        }
        return exp;
    }

    /**
     * 根据玩家的等级获取战场争锋的groupId
     * @return
     */
    public int getGroupId(){
        WorldMapTaskGroupConfig groupConfig = getGroupConfig();
        if(groupConfig == null){
            LogUtils.error(player.name + " 获取玩家当前大地图任务组 为空");
            return 0;
        }
        return groupConfig.id;
    }

    /**
     * 是否会有红点
     * @return
     */
    public boolean checkRedPointRemindAllCondition(){
        for (WorldMapTaskBoxConfig config:canReceiveBoxConfig()){
            if (!boxList.contains(Integer.valueOf(config.id))){
                return true;
            }
        }
        return false;
    }

    /**
     * 获取可以领取的宝箱的列表
     * @return
     */
    public List<WorldMapTaskBoxConfig> canReceiveBoxConfig()
    {
        List<WorldMapTaskBoxConfig> boxConfigList = DataFactory.getInstance().getBoxConfigListByGroup(getGroupConfig().boxGroup);
        List<WorldMapTaskBoxConfig> canReceiveList = new ArrayList<>();
        for (WorldMapTaskBoxConfig config : boxConfigList){
            if (militaryExploitValue >= config.needCount){
                canReceiveList.add(config);
            }
        }
        return canReceiveList;
    }


    /**
     * 获取当前的group
     * @return
     */
    public WorldMapTaskGroupConfig getGroupConfig(){
        List<WorldMapTaskGroupConfig> groupConfigList = DataFactory.getInstance().getDataList(DataFactory.WORLD_MAP_TASK_GROUP);
        groupConfigList.sort((o1,o2)->{
            return o2.id - o1.id;
        });
        for(WorldMapTaskGroupConfig worldMapTaskGroupConfig : groupConfigList)
        {
            if(lastGrade >= worldMapTaskGroupConfig.level)
                return worldMapTaskGroupConfig;
        }
        groupConfigList.sort((o1,o2)->{
            return o1.id - o2.id;
        });
        return groupConfigList.get(groupConfigList.size() - 1);

//        for (int i = 0; i < groupConfigList.size(); i++){
//            WorldMapTaskGroupConfig groupConfig = groupConfigList.get(i);
//            //config取到最后一个直接return
//            if(i+1 == groupConfigList.size()){
//                return groupConfig;
//            }
//            //取到下一个 且玩家等级小于下一个的初始等级 return
//
//            WorldMapTaskGroupConfig nextGroupConfig = groupConfigList.get(i+1);
//            if (lastGrade < nextGroupConfig.level)
//                return groupConfig;
//        }
//        return null;
    }
    /**
     * key 是type value 是 值
     */
    public void addCompleted(CommonData... commonDatas){
        if(commonDatas == null || commonDatas.length == 0){
            return;
        }
        for (CommonData commonData:commonDatas){
            if(commonData == null || commonData.value == 0) {
//                LogUtils.error(player.name + "战场争锋 任务类型" + commonData.id + "增加 null");
                continue;
            }

            addCompleted(SGCommonProto.E_WORLDMAPTASK_TYPE.forNumber(commonData.id), commonData.value);
        }
    }

    public void addCompleted(SGCommonProto.E_WORLDMAPTASK_TYPE type,Long... valueList){
        long value = 0l;
        for (Long integer:valueList){
            value += integer;
        }
        addCompleted(type, value);
    }

    /**
     * 增加三种类型任务的完成度
     * @param type
     * @param value
     */
    public void addCompleted(SGCommonProto.E_WORLDMAPTASK_TYPE type,long value){

        if (value <= 0){
            LogUtils.error("战场争锋：" + type + " 增加完成度参数不正确，value = " + value);
            return;
        }

        WorldMapTaskBean worldMapTaskData = worldMapTaskValues.get(type.getNumber());

        if(worldMapTaskData.getComplete() == null){
            return;
        }

        worldMapTaskData.addComplete(value);

        addDemandToTask(type,value);

        triggerReward(type);
    }

    /**
     * 主线任务 日常任务增加完成度
     */
    public void addDemandToTask(SGCommonProto.E_WORLDMAPTASK_TYPE type,long value){
        //增加用户的任务完成情况
        if (type.equals(SGCommonProto.E_WORLDMAPTASK_TYPE.WORLD_MAP_TASK_KILL_GENERAL)){
            player.getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_WORLDMAP_BATTLE_WIN, (int)value);
        }else if(type.equals(SGCommonProto.E_WORLDMAPTASK_TYPE.WORLD_MAP_TASK_KILL_CARD)){
            player.getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_WORLDMAP_KILL_HURT, (int)value);
        }else if(type.equals(SGCommonProto.E_WORLDMAPTASK_TYPE.WORLD_MAP_TASK_KILL_CITY)){
            player.getExtInfo(TaskInfo.class).check(TaskFactory.TASK_TARAGET_WORLDMAP_OCCUPY_CITY, (int)value);
        }
    }

    /**
     * 清除所有信息
     */
    public void clear()
    {
        militaryExploitValue = 0;
        resetTaskTime = DataFactory.currentTime;
        boxList = new CopyOnWriteArrayList<>();
        battleCardList = new CopyOnWriteArrayList<>();

        initPlayerGrade();
        initTaskId();
    }

    /**
     * 判断是否触发军功奖励
     * @param type
     */
    public void triggerReward(SGCommonProto.E_WORLDMAPTASK_TYPE type)
    {
        //增加军功的时候要判断是否达到上限
        WorldMapTaskGroupConfig worldMapTaskGroupConfig = getGroupConfig();
        if(worldMapTaskGroupConfig == null) {
            LogUtils.error("WorldMapTaskConfig取到为空, lastGrade = " + lastGrade);
            return;
        }

        WorldMapTaskConfig taskConfig;
        WorldMapTaskBean mapTaskData = worldMapTaskValues.get(type.getNumber());
        if(mapTaskData == null)
            return;

        if(mapTaskData.getTaskId() == 0)
            return;

        int size = DataFactory.getInstance().getDataSize(DataFactory.WORLD_MAP_TASK);
        //保证最多只循环这么多次
        for(int i = 0; i < size; i++)
        {
            taskConfig = DataFactory.getInstance().getGameObject(DataFactory.WORLD_MAP_TASK, mapTaskData.getTaskId());
            if(taskConfig == null)
            {
                LogUtils.error("获取WorldMapTaskConfig错误 -> id:" + mapTaskData.getTaskId());
                return;
            }
            if(!mapTaskData.isComplete(taskConfig.count))
                return;

            int addValue = worldMapTaskGroupConfig.count >= militaryExploitValue + taskConfig.reward ? taskConfig.reward : worldMapTaskGroupConfig.count - militaryExploitValue;
            LogUtils.debug("addValue -> " + addValue);
            if(addValue > 0){
                //如果当前的完成度达到需求 增加军功奖励
                //并且给同等的经验奖励
                int beforeLv = player.getLv();
                player.addExp(addValue);
                player.addChangeGoods(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_ASSETS, ConfigFactory.ASSET_EXP_KEY, addValue, player.getExp(), true);
                if(beforeLv != player.getLv())
                {
                    player.addChangeGoods(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_OTHER, SGCommonProto.E_GOODS_OTHER_ID.GOODS_OTHER_ID_LV_VALUE, player.getLv() - beforeLv, player.getLv(),true);

                    int beforeFC = player.fc;

                    player.updateFC();

                    player.addChangeGoods(SGCommonProto.E_GOODS_TYPE.GOODS_TYPE_OTHER, SGCommonProto.E_GOODS_OTHER_ID.GOODS_OTHER_ID_FC_VALUE, player.fc - beforeFC, player.fc, true);
                }
            }
            //军功会一直增加 经验有上限
            militaryExploitValue += taskConfig.reward;
            mapTaskData.setTaskId(taskConfig.next);
            //修改当前任务
//            if(getWorldMapTaskConfig(taskConfig.next) == null){
//                LogUtils.debug(player.name + "今日战场争锋 类型:" + type + "任务全部完成！");
//            }
        }
    }



    public long getComplete(Integer type){
        WorldMapTaskBean bean =  worldMapTaskValues.get(type);
        if(bean != null){
            return bean.getComplete();
        }
        return 0l;
    }

    public long getComplete(SGCommonProto.E_WORLDMAPTASK_TYPE type) {
        return getComplete(type.getNumber());
    }



    public static WorldMapTaskGroupConfig getWorldMapTaskValueConfig(int group){
        List<WorldMapTaskGroupConfig> valueConfigList = DataFactory.getInstance().getDataList(DataFactory.WORLD_MAP_TASK_GROUP);
        for (WorldMapTaskGroupConfig valueConfig:valueConfigList){
            if (valueConfig.boxGroup == group){
                return valueConfig;
            }
        }
        return null;
    }

    public static WorldMapTaskBoxConfig getWorldMapTaskBoxConfig(int key){
        return DataFactory.getInstance().getGameObject(DataFactory.WORLD_MAP_TASK_BOX,key);
    }

    public void setBattleCardList(List<CardDB> list)
    {
        battleCardList.clear();

        for(CardDB cardDB : list)
        {
            battleCardList.add(new CardDB(cardDB));
        }
    }

    public HegemonyScoreChangeBean battleResult(WorldMapBeKillBean beKillBean, boolean result, String masterPlayerIndex)
    {
        if(result)
            return killData.win(beKillBean, masterPlayerIndex);
        else
            killData.lose(masterPlayerIndex);

        return null;
    }

    public WorldMapKillData getKillData() {
        return killData;
    }

    public List<CardDB> getBattleCardList()
    {
        return battleCardList;
    }

    public void clearBattleCardList()
    {
        this.battleCardList.clear();
    }

    public int getMilitaryExploitValue() {
        return militaryExploitValue;
    }

    public void setMilitaryExploitValue(int militaryExploitValue) {
        this.militaryExploitValue = militaryExploitValue;
    }

    public int getLastGrade() {
        return lastGrade;
    }

    public void setLastGrade(int lastGrade) {
        this.lastGrade = lastGrade;
    }

    public List<Integer> getBoxList() {
        return boxList;
    }

    public void setBoxList(List<Integer> boxList) {
        this.boxList = boxList;
    }

    public Map<Integer, WorldMapTaskBean> getWorldMapTaskValues() {
        return worldMapTaskValues;
    }

    public void setWorldMapTaskValues(Map<Integer, WorldMapTaskBean> worldMapTaskValues) {
        this.worldMapTaskValues = worldMapTaskValues;
    }

    public long getResetTaskTime() {
        return resetTaskTime;
    }

    public void setResetTaskTime(long resetTaskTime) {
        this.resetTaskTime = resetTaskTime;
    }

    public boolean isSingleMapEnd() {
        return singleMapEnd;
    }

    public void setSingleMapEnd(boolean singleMapEnd) {
        this.singleMapEnd = singleMapEnd;
    }
}
